<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
    <script>

        let data = {
            msg: 'hello world',
            age: 18
        }

        const vm = new Vue({
            el:'#app',
            // template:'<div>hhh</div>',
            // data:{}
            // 如果data是一个函数，每次创建一个vue组件的时候
            // data里面的数据，都不会相互有影响~~
            data:function(){
                return {
                    msg:'hello',
                    age:18
                }
            },
            created() {
                console.log(this.msg)
            },
        })
        // 如果有el，就会自动调用$mount()
        // 如果没有el，有template，需要手动调用$mount
        console.log(vm)

        // vm.msg  ===>  访问的是 data函数return出来的对象中的msg
        // vm.age  ===> {age:18}
        // vm.msg / vm.age  ===> data中的msg和age

        // this.msg ===> 代理了 data 中的 msg 

        // Vue中，生命周期/方法中等待， this指向的就是vm实例 

        // 1. Vue中的数据代理
        // 通过vm对象代理了data对象中属性的操作（读/写） 
        // 2. Vue中数据代理的好处
        // 更加方便的操作data中的数据 
        // this.msg  =>  vm._data.msg

        // 3. 基本原理 
        // 通过Object.defineProperty 把 data中的所有属性 添加到 vm对象上，
        // 为每一个添加的属性，都设置getter和setter方法，在getter和setter方法内部去操作
        // data中对应的属性

        // let vm = {}


        // Vue内部做了这个处理
        Object.defineProperty(vm, 'msg', {
            configurable:true,
            enumerable:true,
            //value + writable  ==> 不能 和  get 和set共存 
            get: function(){
                console.log('getter函数被调用了')
                return data.msg 
            },
            set(newVal){
                // 处理逻辑
                console.log('setter函数被调用了')
                // obj.x = '某个值'
                data.msg = newVal
            }
        })

        Object.defineProperty(vm, 'age', {
            configurable:true,
            enumerable:true,
            //value + writable  ==> 不能 和  get 和set共存 
            get: function(){
                console.log('getter函数被调用了')
                return data.age 
            },
            set(newVal){
                // 处理逻辑
                console.log('setter函数被调用了')
                // obj.x = '某个值'
                data.age = newVal
            }
        })
        // vm.msg ==> data.msg 

    </script>
</body>
</html>